package com.gitee.huanminabc.utils_tools.config_refresh.utils;
import com.gitee.huanminabc.jcommon.str.StringIdentifyUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.context.expression.BeanFactoryAccessor;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

/**
 * SpEL表达式解析工具类
 */
public class SpELUtil {
    private static ExpressionParser parser;
    static {
      parser =new SpelExpressionParser();
    }

    public static <T> T spElParser(String spEl, Class<T> type, ApplicationContext context){
        //去掉占位符和补充单引号
        spEl = symbolParser(spEl, context);
        // 将ioc容器设置到上下文中
        StandardEvaluationContext standardEvaluationContext = new StandardEvaluationContext(context);
        standardEvaluationContext.addPropertyAccessor(new BeanFactoryAccessor());
        return  parser.parseExpression(spEl).getValue(standardEvaluationContext, type);
    }

    //占位符解析
    public static  <T> String symbolParser(String expression, ApplicationContext context){
    //如果有${}占位符,那么就从ioc容器中获取值
        if (expression.contains("${")) {
            // 取出${}中的值
            String key = expression.substring(expression.indexOf("${") + 2, expression.indexOf("}"));
            //判断是否有:
            if (key.contains(":")){
                String[] split = key.split(":");
                String property = context.getEnvironment().getProperty(split[0]);
                if (property==null){
                    //如果没有值,那么就使用默认值
                    expression = expression.replace("${" + key + "}", split[1]);
                }else{
                    expression = expression.replace("${" + key + "}", property);
                }
            }else{
                String property = context.getEnvironment().getProperty(key);
                if (property==null){
                    //如果没有值,那么就使用占位符本身的值
                    expression = expression.replace("${" + key + "}", key);
                }else{
                    expression = expression.replace("${" + key + "}", property);
                }
            }
            //如果含多个占位符,那么就递归解析
            expression=symbolParser(expression, context);
        }
        if (expression.startsWith("#{")){ //如果开头是#{},那么就是spel表达式
            //去掉#{}
            expression = expression.substring(2, expression.length() - 1);
            return expression;
        }
        // 如果不是表达式,那么就是普通的值,那么就需要判断是否是数字,非数字的话就加上单引号
        boolean numeric = StringIdentifyUtil.isNumeric(expression);
        if (!expression.startsWith("'")&&!numeric){
            //如果不是数字那么就添加单引号
            expression = "'" + expression + "'";
        }
        return expression;
    }
}
